/*
 * A NumberFormatException will never be thrown as the text being parsed is not 
 * editable to the user.
 */
// $codepro.audit.disable handleNumericParsingErrors
/*
 * The longer method chain lengths are named correctly and are readable.
 * They are also indexed in such a way as to be readable as well.
 */
// $codepro.audit.disable methodChainLength
/*
 * A value that is known to be null is being dereferenced in a way that 
 * is guaranteed to produce a NullPointerException, except that the value 
 * will never be null as the offending line in the listener isn't added until 
 * the text has been assigned a value, so it is fine.
 */
// $codepro.audit.disable nullPointerDereference
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JSpinner;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 * 
 * @author John J Storey
 * @version 13
 */
public class SpaceTraderBuy extends JFrame {

	/**
	 * Model for the game.
	 */
	protected Model model;
	
	/**
	 * Main GUI for the game.
	 */
	protected View view;
	
	/**
	 * Button in main GUI.
	 */
	protected JButton parent;
	
	/**
	 * The frame for the new window.
	 */
	private JFrame frame = null;
	
	/**
	 * Index for market and index for planet.
	 */
	protected int index = 0, planet = 0;
	
	/**
	 * Spinner to choose how much to buy.
	 */
	private JSpinner spinner = null;
	
	/**
	 * Labels to be updated.
	 */
	public JLabel lblYouCanBuy, lblPriceEach = null;

	/**
	 * The buy GUI
	 * 
	 * @param model
	 * @param parent
	 * @param view
	 * @param index
	 * @param planet
	 */
	public SpaceTraderBuy(Model model, JButton parent, View view, int index,
			int planet) {
		setSize(new Dimension(450, 185));
		setTitle("Buy Goods");
		getContentPane().setLayout(null);
		this.planet = planet;
		this.model = model;
		this.parent = parent;
		this.view = view;
		this.index = index;
		frame = this;

		spinner = new JSpinner();
		spinner.setModel(new SpinnerNumberModel(1, 1, model.getUniverse()
				.getPlanet(planet).getMarket().getGoodsArray()[index]
				.getCount(), 1));
		((JSpinner.DefaultEditor) spinner.getEditor()).getTextField()
				.setEditable(false);
		spinner.setBounds(272, 56, 56, 20);
		spinner.addChangeListener(listener);
		getContentPane().add(spinner);

		final JLabel lblHowManyWould = new JLabel("How many would you like to buy?");
		lblHowManyWould.setBounds(42, 59, 220, 14);
		getContentPane().add(lblHowManyWould);

		final JButton btnBuy = new JButton("Buy");
		btnBuy.setBounds(173, 110, 89, 23);
		btnBuy.addActionListener(buyActListener);
		getContentPane().add(btnBuy);

		lblYouCanBuy = new JLabel("You can buy up to "
				+ model.getUniverse().getPlanet(planet).getMarket()
						.getGoodsArray()[index].getCount());
		lblYouCanBuy.setBounds(42, 11, 135, 14);
		getContentPane().add(lblYouCanBuy);

		lblPriceEach = new JLabel(""
				+ (Integer) spinner.getValue()
				* model.getUniverse().getPlanet(planet).getMarket()
						.getGoodsArray()[index].getPrice());
		lblPriceEach.setBounds(282, 11, 82, 14);
		getContentPane().add(lblPriceEach);

		final JLabel lblTotal = new JLabel("Total:");
		lblTotal.setBounds(243, 11, 35, 14);
		getContentPane().add(lblTotal);
	}

	/**
	 * Listener that updates player's credits, ship's cargo, and the market.
	 */
	private final ActionListener buyActListener = new ActionListener() {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			if (Integer.parseInt(parent.getText()) == 0) { 
				JOptionPane.showMessageDialog(frame, "Out Of Stock!");
			} else if (model.getPlayer().getCredits() < ((Integer) spinner
					.getValue())
					* (model.getUniverse().getPlanet(planet).getMarket()
							.getGoodsArray()[index].getPrice())) {
				JOptionPane.showMessageDialog(frame, "Insufficient Funds!");
			} else if (model.getShip().getMaxBay() - model.getShip().getCargo() < 
					(Integer) spinner.getValue()) {
				JOptionPane.showMessageDialog(frame,
						"Insufficient Cargo Space!");
			} else {
				model.getPlayer().setCredit(
						model.getPlayer().getCredits()
								- ((Integer) spinner.getValue() * model
										.getUniverse().getPlanet(planet)
										.getMarket().getGoodsArray()[index]
										.getPrice()));
				model.getShip().setCargo(
						model.getShip().getCargo()
								+ (Integer) spinner.getValue());
				view.sell[index].setText("" + spinner.getValue());
				model.getUniverse().getPlanet(planet).getMarket()
						.getGoodsArray()[index].setCount(-(Integer) spinner
						.getValue());
				view.buy[index].setText(model.getUniverse().getPlanet(planet)
						.getMarket().getGoodsArray()[index].getCountString());
				model.getShip().getGoodsArray()[index]
						.setSold((Integer) spinner.getValue());
				view.setBay();
				view.setCurrency();
			}
			processWindowEvent(new WindowEvent(frame,
					WindowEvent.WINDOW_CLOSING));
		}
	};
    
	/**
	 * Listener for the spinner to update text in the GUI.
	 */
	private final ChangeListener listener = new ChangeListener() {

		@Override
		public void stateChanged(ChangeEvent arg0) {
			lblPriceEach.setText(""
					+ (Integer) spinner.getValue()
					* model.getUniverse().getPlanet(planet).getMarket()
							.getGoodsArray()[index].getPrice());
		}
	};
}
